package net.maku.controller;

import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.databind.JsonNode;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpService;
import net.maku.bean.model.MyException;
import net.maku.bean.param.ProxyParam;
import net.maku.bean.param.WeixinAppParam;
import net.maku.bean.param.WeixinParam;
import net.maku.bean.vo.UserTokenVo;
import net.maku.bean.vo.WebUserVO;
import net.maku.config.WxConfigProperties;
import net.maku.entity.WebUserEntity;
import net.maku.service.impl.LoginInfoServiceImpl;
import net.maku.utils.JsonUtils;
import net.maku.utils.Result;
import net.maku.utils.WeChatDecrypt;

@Slf4j
@RestController
@AllArgsConstructor
@Tag(name="微信信息处理")
public class WxMaUserController {
	
	private final WxMaService wxMaService;
 
	@Autowired
	WxConfigProperties  wxConfigProperties;
	
	@Autowired
    LoginInfoServiceImpl loginInfoServiceImpl;
	
	/**
     * 登陆接口
     */
	/*
	@Operation(summary = "微信登录")
    @RequestMapping("/weixinuserlogin")
    public Result<UserTokenVo> wxUserLogin( @RequestBody @Valid WeixinParam query ){
		log.info( query.toString() );

		if (StringUtils.isBlank(query.getCode())) {
            //return Result.error("请求码没有");
        }
        query.setAppid(wxMaService.getWxMaConfig().getAppid());
        try {
            WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(query.getCode());
            log.info( JsonUtils.toJson(session) );
            
            String str = WeChatDecrypt.decrypt(query.getEncryptedData(), session.getSessionKey(), query.getIv() );
            log.info( str );

            String phone = JsonUtils.getStr(str, "phoneNumber");
            log.info( query.getNickName() );
            log.info( query.getHeaderImage() );
            log.info( query.getHeaderImage().length() );
            log.info( phone );
            log.info( session.getOpenid() );
            query.setOpenid(session.getOpenid());
            return Result.ok( loginInfoServiceImpl.userLogin( query, phone) );

        } catch ( Exception e) {
        	e.printStackTrace();
        	log.error("调用微信认证失败" , e);
        }
        return Result.error( "登录失败" );
	}
*/
	
	
	@Operation(summary = "微信登录")
    @RequestMapping("/weixinapplogin")
    public Result<UserTokenVo> wxUserLogin( @RequestBody @Valid WeixinAppParam query ){
		log.info( query.toString() );
		return Result.ok( loginInfoServiceImpl.userAppLogin( query ) );
	}
	
	
	/*
    private void downloadFile(String url, String outputFilePath) {
        RestTemplate restTemplate = new RestTemplate();
        // 发送 GET 请求
        ResponseEntity<byte[]> response = restTemplate.getForEntity(url, byte[].class);
        if (response.getStatusCode().is2xxSuccessful()) {
            byte[] fileBytes = response.getBody();

            // 将字节数组写入文件
            try (FileOutputStream fos = new FileOutputStream(outputFilePath)) {
                fos.write(fileBytes);
                log.info("下载完成，文件已保存至: " + outputFilePath);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            log.info("请求失败，状态码: " + response.getStatusCode());
        }
    }*/


    /**
     * 登陆接口
     */
	@Operation(summary = "微信登录")
    @RequestMapping("/weixinlogin")
    public Result<UserTokenVo> login( @RequestBody @Valid WeixinParam query){
		log.info( query.toString() );
		//log.info( wxConfigProperties.toString() );
        if (StringUtils.isBlank(query.getCode())) {
            return Result.error("请求码没有");
        }
        query.setAppid(wxMaService.getWxMaConfig().getAppid());
        try {
            WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(query.getCode());
            log.info( JsonUtils.toJson(session) );

            WxMaUserInfo userInfo = wxMaService.getUserService().getUserInfo( session.getSessionKey(),
            		query.getEncryptedData(), query.getIv() );
            WxMaConfigHolder.remove();//清理ThreadLocal
            log.info("=================userInfo======================");
            log.info( JsonUtils.toJson(userInfo) );

            String str = WeChatDecrypt.decrypt(query.getEncryptedData(), session.getSessionKey(), query.getIv() );
            log.info( str );

            JsonNode jsonNode = JsonUtils.fromJson( str );
            WebUserEntity bean = new WebUserEntity();
            bean.setAvatar( query.getHeaderImage() );
            bean.setOpenid( jsonNode.get("openId").textValue() );
            bean.setUsername( jsonNode.get("nickName").textValue() );
            bean.setGender( jsonNode.get("gender").asInt() );
            //bean.setAvatar( jsonNode.get("avatarUrl").textValue() );
            bean.setUnionid( jsonNode.get("unionId").textValue() );
            if( session.getOpenid().equals( bean.getOpenid() )){
            	log.info("----------------success--------------------------");
            	return Result.ok( loginInfoServiceImpl.userLogin(bean, query) );
            }
        } catch ( Exception e) {
        	e.printStackTrace();
        	log.error("调用微信认证失败" , e);
        }
        return Result.error( "登录失败" );
    }
	
	
	@Operation(summary = "绑定手机号")
	@PostMapping("/bindphone")
    public Result<UserTokenVo> bindPhone( @RequestBody @Valid WeixinParam query){
		query.setAppid(wxMaService.getWxMaConfig().getAppid());
        try {
            WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(query.getCode());
            log.info( JsonUtils.toJson(session) );
            
            String str = WeChatDecrypt.decrypt(query.getEncryptedData(), session.getSessionKey(), query.getIv() );
            log.info( str );

            String phone = JsonUtils.getStr(str, "phoneNumber");
            log.info( query.getNickName() );
            log.info( query.getHeaderImage() );
            log.info( phone );
            log.info( session.getOpenid() );
            query.setOpenid(session.getOpenid());
            return Result.ok( loginInfoServiceImpl.userLogin( query, phone) );

        } catch ( Exception e) {
        	e.printStackTrace();
        	log.error("调用微信认证失败" , e);
        }
        return Result.error( "登录失败" );
	}
	
	@Operation(summary = "修改头像")
    @PostMapping("/updateheadimg")
    public Result<String> updateHeadImg( @RequestBody @Valid WeixinParam query){
		log.info( "===========updateHeadImg=========================" );
		loginInfoServiceImpl.updateHeadimg(query);
		return Result.ok( "修改头像成功" );
	}
	
	@Operation(summary = "修改昵称")
    @PostMapping("/updatenickname")
    public Result<String> updateNickname( @RequestBody @Valid WeixinParam query){
		log.info( "===========updateNickname=========================" );
		loginInfoServiceImpl.updateNickName(query);
		return Result.ok( "修改昵称成功" );
	}
	
	@Operation(summary = "修改渠道")
    @PostMapping("/updateproxy")
    public Result<String> updateProxy( @RequestBody @Valid ProxyParam query){
		log.info( "===========updateProxy=========================" );
		loginInfoServiceImpl.updateProxy(query.getPhone());
		return Result.ok( "修改渠道成功" );
	}


	@RequestMapping("/flushtoken")
    @Operation(summary = "刷新token")
    public Result<UserTokenVo> flushToken(){
		return Result.ok( loginInfoServiceImpl.flushToken() );
	}

    //@Session
    @RequestMapping("/getuserinfo")
    @Operation(summary = "缓存用户登录")
    public Result<WebUserVO> getuserinfo(){
    	WebUserVO bean = loginInfoServiceImpl.getUserInfo(1);
    	log.info( "==============getuserinfo======================" );
    	log.info( bean.toString() );
    	return Result.ok(bean);
    }
    
    @RequestMapping("/getrealuserinfo")
    @Operation(summary = "实时用户登录")
    public Result<WebUserVO> getRealUserInfo(){
    	WebUserVO bean = loginInfoServiceImpl.getUserInfo(1);
    	log.info( "====================================" );
    	log.info( bean.toString() );
    	return Result.ok(bean);
    }
	
}


